package com.example.springboottools.utils;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {
    /**
     *
     * @param url
     * @param headers
     * @param parameters
     * @param isSsl
     * @return
     */
    public static String httpPostStr(final String url, Map<String, String> headers, Map<String, Object> parameters, boolean isSsl) {
        try {
            HttpEntity httpEntity = httpPost(url, headers, parameters, isSsl);
            return EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     *
     * @param url
     * @param headers
     * @param parameters
     * @param isSsl
     * @return
     */
    public static HttpEntity httpPost(final String url, Map<String, String> headers, Map<String, Object> parameters, boolean isSsl) {
        CloseableHttpClient httpClient = !isSsl ? buildDefaultHttpClient() : buildDefaultHttpClientTrustSSL();
        HttpPost http = new HttpPost(url);

        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                http.addHeader(key, headers.get(key));
            }
        }

        // 设置请求参数
        HttpEntity entity = new UrlEncodedFormEntity(createParam(parameters), Consts.UTF_8);
        http.setEntity(entity);

        try {
            System.out.println(JSON.toJSONString(http));
            CloseableHttpResponse resp = httpClient.execute(http);
            return resp.getEntity();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     *
     * @param paramMap
     * @return
     */
    private static List<NameValuePair> createParam(Map<String, Object> paramMap) {
        // 建立一个NameValuePair数组，用于存储欲传送的参数
        List<NameValuePair> nvpList = Lists.newArrayList();
        if(paramMap != null) {
            for(String k : paramMap.keySet()) {
                nvpList.add(new BasicNameValuePair(k, paramMap.get(k).toString()));
            }
        }
        return nvpList;
    }
    /**
     * 返回HttpClient（忽略SSL证书认证）
     *
     * @return
     */
    private static CloseableHttpClient buildDefaultHttpClientTrustSSL() {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder
                    .create()
                    .setProtocol(SSLConnectionSocketFactory.SSL)
                    .loadTrustMaterial((x, y) -> true)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        RequestConfig config = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setContentCompressionEnabled(true)
                .build();
        return HttpClientBuilder
                .create()
                .setDefaultRequestConfig(config)
                .setSSLContext(sslContext)
                .setSSLHostnameVerifier((x, y) -> true)
                .build();
    }
    /**
     * 返回HttpClient
     * @return
     */
    private static CloseableHttpClient buildDefaultHttpClient() {
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setContentCompressionEnabled(true)
                .build();

        return HttpClients
                .custom()
                .setDefaultRequestConfig(defaultRequestConfig)
                .build();
    }
}
